function conditionalForecastDecompositionClean(names,setStru,histStru,groupStruct,KFStru,forcStru,stateStruct,model,groupNum)


%% Location 

%outputFolder = setStru.savePath;
%outputFolder = ['C:\Users\g1exs02\Documents\ChiDSGE\Memo\Output\G ' num2str(groupNum)];
%% Groups of shocks to decompose

% Options for plots
plotStruct=plotAssignDefaults([]);
plotStruct.sameSubplot=true; 
plotStruct.sameScale=true; 
plotStruct.plotResidual=false; 
plotStruct.plotInitial=true; 
flags.plotForecasts=false; 
plotStruct.plotBars=true; 


%==========================================================================
%% 1. Load following variables from Workspace 


fprintf('Sample End-Point=%2.4f',setStru.dataVec(end)); 
pause(0.5); 

%% 



%% 2. Define nameStru, Structure with the Names 
shockNames=names.shocks.long;
stateNames = names.states;
Znames = names.observables;
nameStru.stateNames=stateNames;
nameStru.shockNames=shockNames;
nameStru.obsNames=Znames;

%% 3. *groupIndicators* structure with the grouping of shocks 
% Position of states to report
report.pos = cellposition(histStru.report,stateNames);
% Structure holding positions and names of groups
groupIndicators= zb_extractgroups(groupStruct,shockNames,histStru,groupNum); 
groupIndicators.Ngroups=length(histStru.groupnames{groupNum}); 




%% 4. Fill in histStru with all the forecast & sample information 
% pos.eta: position of the shocks that will be fed, i.e. forecasting sample
histStru.pos.eta=find( histStru.targetDate>= setStru.dataVec & setStru.dataVec > histStru.jumpDate); 
% pos.states: contains one more observation than eta, the initial jump
% state 
histStru.pos.states = find( histStru.targetDate>= setStru.dataVec & setStru.dataVec >=histStru.jumpDate);
histStru.jumpState=KFStru.smoothSt(find( setStru.dataVec == histStru.jumpDate    ) ,:);  
histStru.eta=KFStru.innovations(histStru.pos.eta,:); 
histStru.sample.forecast=setStru.dataVec( histStru.pos.eta );
histStru.sample.forWithInitial=setStru.dataVec( histStru.pos.states); 
histStru.Nforc =length(histStru.sample.forecast);
histStru.population =forcStru.population.fullPopSeries(histStru.pos.eta); 
%Calendar for jumping points
%histStru.sample.jumpDates=(histStru.jumpDate):0.25:(histStru.targetDate-.25); 
histStru.sample.forecastCell=sample2date(histStru.sample.forecast); 
histStru.sample.forWithInitialCell=sample2date(histStru.sample.forWithInitial); 


%% 5. *outputFolder* folder where output will be stored 
% outputFolder=['Forecast Decomp ',...
%     histStru.sample.forecastCell{1},' ',histStru.sample.forecastCell{end}];
% if ~isempty(addOutputFolder); 
%     outputFolder=[addOutputFolder,outputFolder]; 
% end 


if histStru.flags.flagPlotStates==1 
    stateStruct.position=find( stateStruct.endDate >= setStru.dataVec & setStru.dataVec >= stateStruct.startDate ); 
    stateStruct.sampleVec=setStru.dataVec( stateStruct.position ); 
    stateStruct.samplecell=sample2date( stateStruct.sampleVec ); 
    stateStruct.statesMat=KFStru.smoothSt(stateStruct.position,:);     
    tempExtract=assignXTicksQuarterly(stateStruct.sampleVec,7);
    stateStruct.graphs.xtickValues=stateStruct.sampleVec( tempExtract ); 
    stateStruct.graphs.xtickLabels=stateStruct.samplecell(tempExtract ); 
    stateStruct.graphs.colors=[0 0 1]; 
    stateStruct.graphs.markers={'*'}; 
    stateStruct.graphs.markersSize=5;
    stateStruct.graphs.paperPosition=[0.8 0.7 7 9]; 
    stateStruct.graphs.extract=stateStruct.report; 
    stateStruct.names.colNames=stateNames;  %stateStruct.names.graphs; 
    stateStruct.graphs.suptitle={'Selected States'}; 
    graphsVec=plotStates(stateStruct.statesMat,stateStruct,stateStruct.graphs,stateStruct.names); 
    %compileGraphsPDF(graphsVec,'Selected States',cd);

    for ii=1:length(graphsVec);
        print(graphsVec(ii),'-dpsc',fullfile(setStru.savePath,'Selected States'),'-append');
        %print(graphsVec(ii),'-dpdf',['select states',num2str(ii)],'-append');
    end

    stateStruct.graphs.suptitle={'Selected Innovations'};
    etaStruct=stateStruct; 
    etaStruct.graphs.extract={'Neutral','CIV+G+NX','ISTS','Price Markup','Labor Disutility',...
        'Discount','Spread','Inflation Drift','Factor 1','Factor 2','Spread MeaErr'}; 
    etaStruct.names.colNames=shockNames;  %stateStruct.names.graphs; 
    etaStruct.etaMat=KFStru.innovations(stateStruct.position,:);    
    graphsVec=plotStates(etaStruct.etaMat,etaStruct,etaStruct.graphs,etaStruct.names);

    for ii=1:length(graphsVec);
        print(graphsVec(ii),'-dpsc',fullfile(setStru.savePath,'Selected Innov'),'-append');
        %print(graphsVec(ii),'-dpdf',['select innov',num2str(ii)],'append');
    end
end



%%=========================================================================
%% 6. Compute conditional forecasts
% Fields in *forecastOut* and *forecastOutTransformed* 
%
% See *conditionalForecastSub.m* for additional documentation 
% 
% Forecasts 
% ==========
%
% *.shocksAllOn*: [Nforc Nser] forecast with all shocks turned on. 
%                  Will match smooth states
% 
% *.shocksAllOff*: [Nforc Nser] forecast with all shocks turned off. 
%                  This is the conditional forecast made back at the jump date 
% 
% *.perGroup*: [Nforc Nser Ngroups] each page is a conditional forecast
%               with that group of shocks only turned on, 
%               according to the partition in *groupIndicators* 
%  
% Forecast Errors 
% ===============

% *error*: [Nforc Nser] forecast error equal to shocksOn- shocksOff forecasts above 
% 
% *errorPerGroup* [Nforc Nser Ngroups] each page is the error in the conditional 
%                 forecast with tha group of shocks only turned on, 
%                 equal to shocksOn-perGroup(:,:,ii) 
% 
% *actual* [Nforc Nser] matrix of smooth states. Must equal *shocksAllOn* 

%% 6.1 *forecastOut* 
%  Forecasts from the jump date to the end date, without transformation 
forecastOut=conditionalForecastSub(report.pos,model.GG(:,:,end),model.RR(:,:,end),model.ZZ(:,:,end),model.CC(:,end),...
    histStru.Nforc,histStru.jumpState,histStru.eta,groupIndicators); 
forecastOut.actual=KFStru.smoothSt(histStru.pos.eta,report.pos); 
checkDif=comparemat(forecastOut.actual,forecastOut.shocksAllOn); 
tol=1e-5; 
if checkDif > tol 
    error('Cannot recover actual state') 
end 
clear checkDif; 

%% 6.2 *forecastOutTransformed* 
% Forecasts from the jump date to the end date, WITH transformation
% according to histStru.transformation 
forecastOutTransformed=conditionalForecastSub(report.pos,model.GG(:,:,end),model.RR(:,:,end),model.ZZ(:,:,end),model.CC(:,end),...
    histStru.Nforc,histStru.jumpState,histStru.eta,groupIndicators,histStru.transformation);
forecastOutTransformed.actual=conditionalForecastTransform(forecastOut.actual,histStru.transformation); 
checkDif=comparemat(forecastOut.actual,forecastOut.shocksAllOn); 
if checkDif > tol 
    error('Cannot recover actual state') 
end 
clear checkDif; 


%=========================================================================
%% Plot output from conditionalForecastDecomposition.m 
%
%% Preliminaries 
% 
% 1) When ploting two lines 
%    First will be data (blue, solid,*) 
%    Second will be forecast (black,--,.)
%    No horizontal line 
%    Legends inside graphs 
% 
% 2) Ploting a single line 
%    Same settings as above + horizontal line 
%    at zero -- red, if zero is in the range 
% 
% 3) Bar decompositions superimposed in grey 
% 
plotStruct.lineStyles={'-','--'};
plotStruct.markers   ={'o','x'}; 
plotStruct.markersSize=[3   6]; 
plotStruct.colors    =[0   0  1; 
                       0   0  0]; 
plotStruct.lineWidths=[1.25 1.75]; 
plotStruct.titleFontSize=11; 
plotStruct.suptitleFontSize=plotStruct.titleFontSize+1; 
                 

% Assign Xtick Values and Labels
if plotStruct.plotInitial==true
    tempExtract=assignXTicksQuarterly(histStru.sample.forWithInitial,4);    
    plotStruct.sample=histStru.sample.forWithInitial;
           
    plotStruct.xtickValues=histStru.sample.forWithInitial(tempExtract);
    plotStruct.xtickLabels=histStru.sample.forWithInitialCell(tempExtract);
else
    plotStruct.sample=histStru.sample.forecast;

    tempExtract=assignXTicksQuarterly(histStru.sample.forecast,4);
    plotStruct.xtickValues=histStru.sample.forecast(tempExtract);
    plotStruct.xtickLabels=histStru.sample.forecastCell(tempExtract);
end
clear temp*; 

NgroupsPlot=groupIndicators.Ngroups; 
if ~plotStruct.plotResidual
    NgroupsPlot=NgroupsPlot-1;
end
Nseries=length(histStru.report); 

if exist('yOffset','var')==false 
    yOffset=0.*ones(Nseries,1);
end 

table.transformations=cell(Nseries,2); 
handleFError=zeros(Nseries,1); 

NrowsGraph=ceil( (NgroupsPlot+1 )/2 ); 
plotStruct.description=cell(3,1); 
plotStruct.description(1)={'Notes: In Panels b) through d) the total forecast error (FE) is given by the solid'}; 
plotStruct.description(2)={'line, with grey bars corresponding to the contribution of each group.'}; 

tableStruct.desc={'Tables for each series'}; 

%========================================================================
%% Plot of the forecasts errors
for serInd= 1:Nseries        
    
    if strcmpi( histStru.transformation{serInd} ,'annualize' )==true 
        tempScale=4; 
    else 
        tempScale=1; 
    end 
    
    
    subplotCounter=1;
    handleFError(serInd)=figure;
    
    % No user defined limits on first two plots
    plotStruct.ylim=[];
    plotStruct.yOffset=0;
    
    %% plotStruct.yLabel: change labels depending on transformation
    if strcmp(histStru.report(serInd),'Hours')
        display('Scaling Hrs to 1');
        plotStruct.yLabel='';
        plotStruct.description(3)={['Forecast for untransformed ',histStru.report{serInd},' , conditioning on states in ',...
            histStru.sample.forWithInitialCell{1},'.']};
    elseif strcmpi(histStru.transformation{serInd},'annualize')==true
        plotStruct.yLabel = 'annualized';
        plotStruct.description(3)={['Forecast for ',histStru.report{serInd},' annualized, conditioning on states in ',...
            histStru.sample.forWithInitialCell{1},'.']};
    elseif strcmpi(histStru.transformation{serInd},'cumsum')==true
        plotStruct.yLabel='cum growth rate';
        plotStruct.description(3)={['Forecast for cummulated sum of quarterly ',histStru.report{serInd}...
            ,' growth rate, data as of ',histStru.sample.forWithInitialCell{1},'.']};
    else
        plotStruct.yLabel='';
    end
    
    %% Table transformations
    table.transformations(serInd,1)=histStru.report(serInd);
    table.transformations(serInd,2)={plotStruct.yLabel};
    
    %% actualState: smooth state
    actualState=forecastOutTransformed.actual(:,serInd);
    forecastShocksOff=forecastOutTransformed.shocksAllOff(:,serInd);
    if plotStruct.plotInitial==true
        actualState=[0;actualState(:)];
        forecastShocksOff=[0;forecastShocksOff(:)];
    end
    
    %% First subplot
    %  Actual vs. Forecast
    subplot(NrowsGraph,2,subplotCounter);
    
    plotStruct.legend={'data','forecast'};
    plotStruct.legendLocation='SouthWest';
    plotStruct.legendFontSize=9;
    plotStruct.flagLegendBoxOff=1;
    plotStruct.flagNoLegend=0;
    
    plot3sampSub(plotStruct.sample,...
        [actualState forecastShocksOff],'a) Data and conditional forecast',1,plotStruct);
    
    subplotCounter=subplotCounter+1;
    
    %     %% Second subplot
    %     %  Forecats error
    %     subplot(NrowsGraph,2,subplotCounter);
    %     
    %     plot3sampSub(plotStruct.sample,...
    %         actualState-forecastShocksOff,'b. Forecast Error (FE)',1,plotStruct);
    %
    %     subplotCounter=subplotCounter+1;
    %
    %% plotStruct.y<> : set a common scale
    %  Set YLim for the forecast errors
    plotStruct.flagNoLegend=1;
    
    if plotStruct.sameScale==true
        yMin=min( min( squeeze(forecastOutTransformed.errorPerGroup(:,serInd,:)) ));
        yMax=max(max( squeeze(forecastOutTransformed.errorPerGroup(:,serInd,:)) ));
        yMin=min(yMin,min(forecastOutTransformed.error(:,serInd)))-yOffset(serInd);
        yMax=max(yMax,max(forecastOutTransformed.error(:,serInd)))+yOffset(serInd);
        plotStruct.ylim=[floor(yMin) ceil(yMax)];
    end
    
    
    tempPanelVec={'b)','c)','d)','e)','f)','g)','h)','i)','k)','l)','m)'};
    
    %% Begin plots by group
    for groupInd =1:NgroupsPlot
        
        subplot(NrowsGraph,2,subplotCounter);
 
        plotMat=forecastOutTransformed.errorPerGroup(:,serInd,groupInd);
        if plotStruct.plotInitial==true
            plotMat=[0;plotMat(:)];
        end
        tempTitle=[tempPanelVec{groupInd},' ',histStru.groupnames{groupNum}{groupInd},' FE'];
        
        if plotStruct.plotBars==false
            
            if groupInd == NgroupsPlot
                plotStruct.legend={'total','group'};
                plotStruct.legendLocation='bottom';
                plotStruct.legendFontSize=8;
                plotStruct.flagLegendBoxOff=1;
                plotStruct.flagNoLegend=0;
            end
            handleSubVec=plot3sampSub(plotStruct.sample,...
                [actualState-forecastShocksOff plotMat(:)],tempTitle,1,plotStruct);
        else
            handleSubVec=plot3sampSub(plotStruct.sample,...
                actualState-forecastShocksOff,tempTitle,1,plotStruct);
            hold on;
            handleBar=bar(plotStruct.sample,plotMat,0.95);
            shading(gca,'flat');
            set(handleBar,'FaceColor',[0.7 0.7 0.7])
            hold off;
        end
        
        subplotCounter=subplotCounter+1;
        
        if plotStruct.ylim(1) < 0 && plotStruct.ylim(2) > 0
            hand=hline(0);
            set(hand,'Color',[1 0 0],'LineStyle','--');
        end
    end
    
    %% String and Paper Position 
%     titleString=[histStru.graphNames{serInd},' Forecast error and decomposition ',histStru.sample.forecastCell{1},'-',...
%         histStru.sample.forecastCell{end}];   
%    suptitle(titleString, 12);
    titlecell=cell(2,1); 
    titlecell(1)={[histStru.graphNames{serInd},', Forecast Error and Decomposition ']}; 
    titlecell(2)={['Forecast sample:',histStru.sample.forecastCell{1},'-',histStru.sample.forecastCell{end}]};   
    suptitle(titlecell,plotStruct.suptitleFontSize);
    plotStruct.ylim = [];
    set(handleFError(serInd),'paperPosition', [0.8 0.7 7 9]);

    plotFootnote(plotStruct.description,plotStruct.suptitleFontSize+2); 
    
    %subtitulo('Bottom panels: forecast error (solid), group contribution (bars)');
    
     %% Top Row  Name 
     tableSer=emptycell( histStru.Nforc+4, 6);
     tableSer(1,1)={ histStru.report{serInd} }; 
     tableSer(1,2)={plotStruct.yLabel};
     
    %% Second Row Constants 
    tableSer(2,2:5)={'with mean','with mean','transformed','transformed'}; 

    fldnm=deblank(histStru.report{serInd});
    fldnm=regexprep(fldnm,' ',''); 
    tableSer(1,3)={'Constant'};
    tempCons=histStru.constants(serInd); 
    
    tableSer(1,4)=num2cprec( tempCons );
    tableSer(3,:)={'Date','Actual','Forecast','Actual','Forecast',...
        'Forecast Error'};
    tableSer(4:end,1)=histStru.sample.forWithInitialCell;
    tableSer(4,2)    =num2cprec( tempScale*( KFStru.smoothSt( histStru.pos.states(1) , report.pos( serInd ) ) ) +...
        tempCons , 2); 
    tableSer(5:end,2)=num2cprec( (tempScale*forecastOut.actual(:,serInd)+tempCons ), 2) ; 
    tableSer(5:end,3)=num2cprec( (tempScale*forecastOut.shocksAllOff(:,serInd)+tempCons ), 2);
    tableSer(5:end,4)=num2cprec( forecastOutTransformed.actual(:,serInd), 2); 
    tableSer(5:end,5)=num2cprec( forecastOutTransformed.shocksAllOff(:,serInd), 2); 
    tableSer(5:end,6)=num2cprec( forecastOutTransformed.error(:,serInd), 2); 
    
    tableStruct.(fldnm)=tableSer; 
end
%%

table.colNames=[histStru.groupnames{groupNum}(:);{'Total'}]; 
table.mat=zeros(Nseries,groupIndicators.Ngroups+1); 
for rowInd=1:Nseries 
    for colInd=1:groupIndicators.Ngroups
        table.mat(rowInd,colInd)=forecastOutTransformed.errorPerGroup(end,rowInd,colInd);         
    end
end 
table.mat(:,end)=reshape(   squeeze( sum(forecastOutTransformed.errorPerGroup(end,:,:),3 ) ),1,Nseries);
maxDif=comparemat(table.mat(:,end),forecastOutTransformed.error(end,:,:)');
if maxDif > 1e-8
    error('Wrong residual decomposition')
end

addString=[histStru.sample.forecastCell{1},'_',histStru.sample.forecastCell{end}];
table.caption=['FE Decomposition, End-Point,',addString];
table.cell=crtcell(table.mat,table.transformations(:,1),table.colNames,table.caption,2); 
table.cell=merge_cells(table.cell,table.transformations,2); 


xlsName=fullfile(setStru.savePath,['FE ',addString,' table']); 
xlswrite(xlsName,table.cell,['End ',histStru.sample.forecastCell{end}]);

for serInd=1:Nseries
    fldnm=deblank(histStru.report{serInd});
    fldnm=regexprep(fldnm,' ',''); 
    xlswrite(xlsName,tableStruct.(fldnm),fldnm); 
end 

for ii=1:length(handleFError); 
    print(handleFError(ii),'-dpsc',fullfile(setStru.savePath,['FE ',addString,' figures']),'-append'); 
    %print(handleFError(ii),'-dpdf',['Fig',num2str(ii),' ',addString]); 
end 
%%

